home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1994 August / August CD.bin / Shareware / Programming / SpriteWorld / Sources / SpriteWorld.c < prev    next >
Text File  |  1994-04-25  |  37KB  |  1,318 lines

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteWorld.c
  3. //
  4. //    Created:    Wednesday, May 29, 1991 at 10:43:28 PM
  5. //    By:        Tony Myles
  6. //
  7. //    Copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  8. //
  9. //    Description:    implementation of the sprite world architecture
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __QUICKDRAW__
  18. #include <QuickDraw.h>
  19. #endif
  20.  
  21. #ifndef __MEMORY__
  22. #include <Memory.h>
  23. #endif
  24.  
  25. #ifndef __GESTALTEQU__
  26. #include <GestaltEqu.h>
  27. #endif
  28.  
  29. #ifndef __SPRITEWORLDUTILS__
  30. #include "SpriteWorldUtils.h"
  31. #endif
  32.  
  33. #ifndef __SPRITEWORLD__
  34. #include "SpriteWorld.h"
  35. #endif
  36.  
  37. #ifndef __SPRITELAYER__
  38. #include "SpriteLayer.h"
  39. #endif
  40.  
  41. #ifndef __SPRITE__
  42. #include "Sprite.h"
  43. #endif
  44.  
  45. #ifndef __FRAME__
  46. #include "Frame.h"
  47. #endif
  48.  
  49. #ifndef __BLITPIXIE__
  50. #include "BlitPixie.h"
  51. #endif
  52.  
  53. #if MPW
  54. #pragma segment SpriteWorld
  55. #endif
  56.  
  57. char gSWmmuMode;
  58.  
  59.  
  60. ///--------------------------------------------------------------------------------------
  61. //    SWEnterSpriteWorld
  62. ///--------------------------------------------------------------------------------------
  63.  
  64. SW_FUNC OSErr SWEnterSpriteWorld(void)
  65. {
  66.     OSErr err;
  67.     long    versionNumber;
  68.  
  69.         // make sure we can run in this environment
  70.     err = Gestalt(gestaltTimeMgrVersion, &versionNumber);
  71.  
  72.     if ((err != noErr) || (versionNumber < gestaltStandardTimeMgr))
  73.     {
  74.         err = kTimeMgrNotPresentErr;
  75.     }
  76.  
  77.     if (err == noErr)
  78.     {
  79.         gSWmmuMode = GetMMUMode();
  80.     }
  81.  
  82.     return err;
  83. }
  84.  
  85.  
  86. ///--------------------------------------------------------------------------------------
  87. //    SWExitSpriteWorld
  88. ///--------------------------------------------------------------------------------------
  89.  
  90. SW_FUNC void SWExitSpriteWorld(void)
  91. {
  92.     // nothing happens here right now, but that might change later
  93. }
  94.  
  95.  
  96. ///--------------------------------------------------------------------------------------
  97. //    SWCreateSpriteWorld
  98. ///--------------------------------------------------------------------------------------
  99.  
  100. SW_FUNC OSErr SWCreateSpriteWorld(
  101.     SpriteWorldPtr *spriteWorldP,
  102.     FramePtr windowFrameP,
  103.     FramePtr backFrameP,
  104.     FramePtr loadFrameP)
  105. {
  106.     OSErr err;
  107.     SpriteWorldPtr tempSpriteWorldP;
  108.  
  109.     err = noErr;
  110.     *spriteWorldP = NULL;
  111.  
  112.     tempSpriteWorldP = (SpriteWorldPtr)NewPtrClear((Size)sizeof(SpriteWorldRec));
  113.  
  114.     if (tempSpriteWorldP != NULL)
  115.     {
  116.         tempSpriteWorldP->windowFrameP = windowFrameP;
  117.         tempSpriteWorldP->backFrameP = backFrameP;
  118.         tempSpriteWorldP->loadFrameP = loadFrameP;
  119.         tempSpriteWorldP->eraseDrawProc = SWStdWorldDrawProc;
  120.         tempSpriteWorldP->screenDrawProc = SWStdWorldDrawProc;
  121.  
  122.         *spriteWorldP = tempSpriteWorldP;
  123.     }
  124.     else
  125.     {
  126.         err = MemError();
  127.     }
  128.  
  129.     return err;
  130. }
  131.  
  132.  
  133. ///--------------------------------------------------------------------------------------
  134. //    SWCreateSpriteWorldFromWindow
  135. ///--------------------------------------------------------------------------------------
  136.  
  137. SW_FUNC OSErr SWCreateSpriteWorldFromWindow(
  138.     SpriteWorldPtr* spriteWorldP,
  139.     CWindowPtr srcWindowP,
  140.     Rect* worldRect)
  141. {
  142.     OSErr err;
  143.     CGrafPtr savePort;
  144.     FramePtr windowFrameP, backFrameP, loadFrameP;
  145.     Rect tempRect;
  146.  
  147.     *spriteWorldP = NULL;
  148.     windowFrameP = backFrameP = loadFrameP = NULL;
  149.  
  150.     tempRect = (worldRect == NULL) ? srcWindowP->portRect : *worldRect;
  151.  
  152.     GetPort((GrafPtr*)&savePort);
  153.     SetPort((GrafPtr)srcWindowP);
  154.  
  155.         // create window frame
  156.     err = SWCreateFrame(&windowFrameP, srcWindowP, &tempRect);
  157.  
  158.     if (err == noErr)
  159.     {
  160.             // create back drop frame
  161.         err = SWCreateFrame(&backFrameP, NULL, &tempRect);
  162.     }
  163.  
  164.     if (err == noErr)
  165.     {
  166.             // create loader frame
  167.         err = SWCreateFrame(&loadFrameP, NULL, &tempRect);
  168.     }
  169.  
  170.     if (err == noErr)
  171.     {
  172.             // create sprite world
  173.         err = SWCreateSpriteWorld(spriteWorldP, windowFrameP, backFrameP, loadFrameP);
  174.     }
  175.  
  176.     if (err != noErr)
  177.     {
  178.             // an error occurred so dispose of anything we managed to create
  179.  
  180.         if (windowFrameP != NULL)
  181.         {
  182.             SWDisposeFrame(windowFrameP);
  183.         }
  184.  
  185.         if (backFrameP != NULL)
  186.         {
  187.             SWDisposeFrame(backFrameP);
  188.         }
  189.  
  190.         if (loadFrameP != NULL)
  191.         {
  192.             SWDisposeFrame(loadFrameP);
  193.         }
  194.     }
  195.  
  196.     SetPort((GrafPtr)savePort);
  197.  
  198.     return err;
  199. }
  200.  
  201.  
  202. ///--------------------------------------------------------------------------------------
  203. //    SWDisposeSpriteWorld
  204. ///--------------------------------------------------------------------------------------
  205.  
  206. SW_FUNC void SWDisposeSpriteWorld(
  207.     SpriteWorldPtr spriteWorldP)
  208. {
  209.     if (spriteWorldP != NULL)
  210.     {
  211.         SWDisposeFrame(spriteWorldP->backFrameP);
  212.  
  213.         SWDisposeFrame(spriteWorldP->loadFrameP);
  214.  
  215.         spriteWorldP->windowFrameP->framePort.colorGrafP = NULL;
  216.         SWDisposeFrame(spriteWorldP->windowFrameP);
  217.  
  218.         DisposePtr((Ptr)spriteWorldP);
  219.     }
  220. }
  221.  
  222.  
  223. ///--------------------------------------------------------------------------------------
  224. //    SWAddSpriteLayer
  225. ///--------------------------------------------------------------------------------------
  226.  
  227. SW_FUNC void SWAddSpriteLayer(
  228.     SpriteWorldPtr spriteWorldP,
  229.     SpriteLayerPtr newSpriteLayerP)
  230. {
  231.     SpriteLayerPtr tailSpriteLayerP = spriteWorldP->tailSpriteLayerP;
  232.  
  233.     if (tailSpriteLayerP != NULL)
  234.     {
  235.             // doubly link the new layer
  236.         tailSpriteLayerP->nextSpriteLayerP = newSpriteLayerP;
  237.         newSpriteLayerP->prevSpriteLayerP = tailSpriteLayerP;
  238.         newSpriteLayerP->nextSpriteLayerP = NULL;
  239.     }    
  240.     else
  241.     {
  242.         newSpriteLayerP->prevSpriteLayerP = NULL;
  243.         newSpriteLayerP->nextSpriteLayerP = NULL;
  244.  
  245.             // make the new layer the head
  246.         spriteWorldP->headSpriteLayerP = newSpriteLayerP;
  247.     }
  248.  
  249.         // make the new layer the tail
  250.     spriteWorldP->tailSpriteLayerP = newSpriteLayerP;
  251. }
  252.  
  253.  
  254. ///--------------------------------------------------------------------------------------
  255. //    SWRemoveSpriteLayer
  256. ///--------------------------------------------------------------------------------------
  257.  
  258. SW_FUNC void SWRemoveSpriteLayer(
  259.     SpriteWorldPtr spriteWorldP,
  260.     SpriteLayerPtr oldSpriteLayerP)
  261. {
  262.         // is there a next layer?
  263.     if (oldSpriteLayerP->nextSpriteLayerP != NULL)
  264.     {
  265.             // link the next layer to the prev layer
  266.         oldSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
  267.     }
  268.     else
  269.     {
  270.             // make the prev layer the tail
  271.         spriteWorldP->tailSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
  272.     }
  273.  
  274.         // is there a prev layer?
  275.     if (oldSpriteLayerP->prevSpriteLayerP != NULL)
  276.     {
  277.             // link the prev layer to the next layer
  278.         oldSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
  279.     }
  280.     else
  281.     {
  282.             // make the next layer the head
  283.         spriteWorldP->headSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
  284.     }
  285. }
  286.  
  287.  
  288. ///--------------------------------------------------------------------------------------
  289. //    SWSwapSpriteLayer
  290. ///--------------------------------------------------------------------------------------
  291.  
  292. SW_FUNC void SWSwapSpriteLayer(
  293.     SpriteWorldPtr spriteWorldP,
  294.     SpriteLayerPtr srcSpriteLayerP,
  295.     SpriteLayerPtr dstSpriteLayerP)
  296. {
  297.     register SpriteLayerPtr swapSpriteLayerP;
  298.     
  299.     swapSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
  300.     srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
  301.     dstSpriteLayerP->nextSpriteLayerP = swapSpriteLayerP;
  302.  
  303.     swapSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
  304.     srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
  305.     dstSpriteLayerP->prevSpriteLayerP = swapSpriteLayerP;
  306.  
  307.     if (srcSpriteLayerP->nextSpriteLayerP == NULL)
  308.     {
  309.         spriteWorldP->tailSpriteLayerP = srcSpriteLayerP;
  310.     }
  311.     else if (srcSpriteLayerP->prevSpriteLayerP == NULL)
  312.     {
  313.         spriteWorldP->headSpriteLayerP = srcSpriteLayerP;
  314.     }
  315.  
  316.     if (dstSpriteLayerP->nextSpriteLayerP == NULL)
  317.     {
  318.         spriteWorldP->tailSpriteLayerP = dstSpriteLayerP;
  319.     }
  320.     else if (dstSpriteLayerP->prevSpriteLayerP == NULL)
  321.     {
  322.         spriteWorldP->headSpriteLayerP = dstSpriteLayerP;
  323.     }
  324. }
  325.  
  326.  
  327. ///--------------------------------------------------------------------------------------
  328. //    SWGetNextSpriteLayer
  329. ///--------------------------------------------------------------------------------------
  330.  
  331. SW_FUNC SpriteLayerPtr SWGetNextSpriteLayer(
  332.     SpriteWorldPtr spriteWorldP,
  333.     SpriteLayerPtr curSpriteLayerP)
  334. {
  335.     return (curSpriteLayerP == NULL) ?
  336.             spriteWorldP->headSpriteLayerP :
  337.             curSpriteLayerP->nextSpriteLayerP;
  338. }
  339.  
  340.  
  341. ///--------------------------------------------------------------------------------------
  342. //    SWLockSpriteWorld
  343. ///--------------------------------------------------------------------------------------
  344.  
  345. SW_FUNC void SWLockSpriteWorld(
  346.     SpriteWorldPtr spriteWorldP)
  347. {
  348.     SpriteLayerPtr curSpriteLayerP;
  349.  
  350.     SWLockFrame(spriteWorldP->windowFrameP);
  351.     SWLockFrame(spriteWorldP->backFrameP);
  352.     SWLockFrame(spriteWorldP->loadFrameP);
  353.  
  354.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  355.  
  356.     while (curSpriteLayerP != NULL)
  357.     {
  358.         SWLockSpriteLayer(curSpriteLayerP);
  359.  
  360.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  361.     }
  362. }
  363.  
  364.  
  365. ///--------------------------------------------------------------------------------------
  366. //    SWUnlockSpriteWorld
  367. ///--------------------------------------------------------------------------------------
  368.  
  369. SW_FUNC void SWUnlockSpriteWorld(
  370.     SpriteWorldPtr spriteWorldP)
  371. {
  372.     SpriteLayerPtr curSpriteLayerP;
  373.  
  374.     SWUnlockFrame(spriteWorldP->windowFrameP);
  375.     SWUnlockFrame(spriteWorldP->backFrameP);
  376.     SWUnlockFrame(spriteWorldP->loadFrameP);
  377.  
  378.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  379.  
  380.     while (curSpriteLayerP != NULL)
  381.     {
  382.         SWUnlockSpriteLayer(curSpriteLayerP);
  383.  
  384.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  385.     }
  386. }
  387.  
  388.  
  389. ///--------------------------------------------------------------------------------------
  390. //    SWSetPortToBackGround
  391. ///--------------------------------------------------------------------------------------
  392.  
  393. SW_FUNC void SWSetPortToBackGround(
  394.     SpriteWorldPtr spriteWorldP)
  395. {
  396.     SetPort(spriteWorldP->backFrameP->framePort.monoGrafP);
  397. }
  398.  
  399.  
  400. ///--------------------------------------------------------------------------------------
  401. //    SWSetPortToWindow
  402. ///--------------------------------------------------------------------------------------
  403.  
  404. SW_FUNC void SWSetPortToWindow(
  405.     SpriteWorldPtr spriteWorldP)
  406. {
  407.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  408. }
  409.  
  410.  
  411. ///--------------------------------------------------------------------------------------
  412. //    SWSetSpriteWorldEraseProc
  413. ///--------------------------------------------------------------------------------------
  414.  
  415. SW_FUNC void SWSetSpriteWorldEraseProc(
  416.     SpriteWorldPtr spriteWorldP,
  417.     WorldDrawProcPtr eraseProc)
  418. {
  419.     spriteWorldP->eraseDrawProc = eraseProc;
  420. }
  421.  
  422.  
  423. ///--------------------------------------------------------------------------------------
  424. //    SWSetSpriteWorldDrawProc
  425. ///--------------------------------------------------------------------------------------
  426.  
  427. SW_FUNC void SWSetSpriteWorldDrawProc(
  428.     SpriteWorldPtr spriteWorldP,
  429.     WorldDrawProcPtr drawProc)
  430. {
  431.     spriteWorldP->screenDrawProc = drawProc;
  432. }
  433.  
  434.  
  435. ///--------------------------------------------------------------------------------------
  436. //    SWStdWorldDrawProc
  437. ///--------------------------------------------------------------------------------------
  438.  
  439. SW_FUNC void SWStdWorldDrawProc(
  440.     FramePtr srcFrameP,
  441.     FramePtr dstFrameP,
  442.     Rect* drawRect)
  443. {
  444.     CopyBits((BitMapPtr)srcFrameP->framePix.pixMapP, (BitMapPtr)dstFrameP->framePix.pixMapP,
  445.                 drawRect, drawRect, srcCopy, NULL);
  446. }
  447.  
  448.  
  449. ///--------------------------------------------------------------------------------------
  450. //    SWUpdateSpriteWorld
  451. ///--------------------------------------------------------------------------------------
  452.  
  453. SW_FUNC void SWUpdateSpriteWorld(
  454.     SpriteWorldPtr spriteWorldP)
  455. {
  456.     register SpriteLayerPtr curSpriteLayerP;
  457.     register SpritePtr curSpriteP;
  458.     Rect rgnRect;
  459.  
  460.         // the current port should the one in which we are drawing    
  461.     SetPort(spriteWorldP->loadFrameP->framePort.monoGrafP);
  462.  
  463.     (*spriteWorldP->eraseDrawProc)(spriteWorldP->backFrameP,
  464.                                 spriteWorldP->loadFrameP,
  465.                                 &spriteWorldP->loadFrameP->frameRect);
  466.  
  467.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  468.  
  469.         // iterate through the layers in this world
  470.     while (curSpriteLayerP != NULL)
  471.     {
  472.         curSpriteP = curSpriteLayerP->headSpriteP;
  473.  
  474.             // iterate through the sprites in this layer
  475.         while (curSpriteP != NULL)
  476.         {
  477.             if (curSpriteP->isVisible)
  478.             {
  479.                 if (curSpriteP->curFrameP->maskRgn != NULL)
  480.                 {
  481.                     rgnRect = (**curSpriteP->curFrameP->maskRgn).rgnBBox;
  482.  
  483.                         // move the mask region to the new sprite location
  484.                     OffsetRgn(
  485.                         curSpriteP->curFrameP->maskRgn,
  486.                         (curSpriteP->destFrameRect.left - rgnRect.left) +
  487.                         curSpriteP->curFrameP->offsetPoint.h,
  488.                         (curSpriteP->destFrameRect.top - rgnRect.top) +
  489.                         curSpriteP->curFrameP->offsetPoint.v);
  490.                 }
  491.  
  492.                     // copy the sprite image onto the back drop piece
  493.                 (*curSpriteP->frameDrawProc)(curSpriteP->curFrameP,
  494.                                             spriteWorldP->loadFrameP,
  495.                                             &curSpriteP->curFrameP->frameRect,
  496.                                             &curSpriteP->destFrameRect);
  497.             }
  498.  
  499.             curSpriteP = curSpriteP->nextSpriteP;
  500.         }
  501.  
  502.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  503.     }
  504.  
  505.             // the current port should the one in which we are drawing    
  506.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  507.  
  508.     (*spriteWorldP->screenDrawProc)(spriteWorldP->loadFrameP,
  509.                                     spriteWorldP->windowFrameP,
  510.                                     &spriteWorldP->windowFrameP->frameRect);
  511. }
  512.  
  513.  
  514. ///--------------------------------------------------------------------------------------
  515. //    SWProcessSpriteWorld
  516. ///--------------------------------------------------------------------------------------
  517.  
  518. SW_FUNC void SWProcessSpriteWorld(
  519.     SpriteWorldPtr spriteWorldP)
  520. {
  521.     register SpriteLayerPtr curSpriteLayerP;
  522.     SpriteLayerPtr nextSpriteLayerP;
  523.     register SpritePtr curSpriteP;
  524.     SpritePtr nextSpriteP;
  525.     register FramePtr oldFrameP, newFrameP;
  526.     Point spritePoint, oldPoint;
  527.     short horizOffset, vertOffset;
  528.  
  529.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  530.  
  531.         // iterate through the layers in this world
  532.     while (curSpriteLayerP != NULL)
  533.     {
  534.         nextSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  535.         curSpriteP = curSpriteLayerP->headSpriteP;
  536.  
  537.             // iterate through the sprites in this layer
  538.         while (curSpriteP != NULL)
  539.         {
  540.             nextSpriteP = curSpriteP->nextSpriteP;
  541.  
  542.                 // is it time to advance the sprite’s frame?
  543.             if (curSpriteP->frameTimeTask.hasTaskFired)
  544.             {
  545.                 curSpriteP->curFrameIndex += curSpriteP->frameAdvance;
  546.  
  547.                 if (curSpriteP->curFrameIndex < curSpriteP->firstFrameIndex)
  548.                 {
  549.                         // wrap to the last frame
  550.                     curSpriteP->curFrameIndex = curSpriteP->lastFrameIndex;
  551.                 }
  552.                 else if (curSpriteP->curFrameIndex > curSpriteP->lastFrameIndex)
  553.                 {
  554.                         // wrap to the first frame
  555.                     curSpriteP->curFrameIndex = curSpriteP->firstFrameIndex;
  556.                 }
  557.  
  558.                     // get new frame
  559.                 newFrameP =    curSpriteP->frameArray[curSpriteP->curFrameIndex];
  560.  
  561.                     // is there a frame callback?
  562.                 if (curSpriteP->frameChangeProc != NULL)
  563.                 {
  564.                         // call it
  565.                     (*curSpriteP->frameChangeProc)(curSpriteP, newFrameP,
  566.                             &curSpriteP->curFrameIndex);
  567.  
  568.                         // make sure the new frame index is in range
  569.                     if (curSpriteP->curFrameIndex < 0)
  570.                     {
  571.                         curSpriteP->curFrameIndex = 0;
  572.                     }
  573.                     else if (curSpriteP->curFrameIndex >= curSpriteP->maxFrames)
  574.                     {
  575.                         curSpriteP->curFrameIndex = curSpriteP->maxFrames - 1;
  576.                     }
  577.                 }
  578.  
  579.                     // change the frame
  580.                 newFrameP =    curSpriteP->frameArray[curSpriteP->curFrameIndex];
  581.  
  582.                     // has the frame actually changed?
  583.                 if (curSpriteP->curFrameP != newFrameP)
  584.                 {
  585.                     oldFrameP = curSpriteP->curFrameP;
  586.                     curSpriteP->curFrameP = newFrameP;
  587.  
  588.                     horizOffset = (curSpriteP->destFrameRect.left - newFrameP->frameRect.left);
  589.                     vertOffset = (curSpriteP->destFrameRect.top - newFrameP->frameRect.top);
  590.  
  591.                     curSpriteP->destFrameRect = newFrameP->frameRect;
  592.  
  593.                     curSpriteP->destFrameRect.left += horizOffset;
  594.                     curSpriteP->destFrameRect.right += horizOffset;
  595.                     curSpriteP->destFrameRect.top += vertOffset;
  596.                     curSpriteP->destFrameRect.bottom += vertOffset;
  597.  
  598.                     curSpriteP->needsToBeDrawn = true;
  599.                 }
  600.  
  601.                 if (curSpriteP->frameTimeInterval > 0)
  602.                 {
  603.                     curSpriteP->frameTimeTask.hasTaskFired = false;
  604.  
  605.                         // reset the time till next frame
  606.                     PrimeTime((QElemPtr)&curSpriteP->frameTimeTask, curSpriteP->frameTimeInterval);
  607.                 }
  608.             }
  609.  
  610.                 // is it time to move the sprite?
  611.             if (curSpriteP->moveTimeTask.hasTaskFired)
  612.             {
  613.                     // is there a movement callback?
  614.                 if (curSpriteP->spriteMoveProc != NULL)
  615.                 {
  616.                     oldPoint = *(Point*)&(curSpriteP->destFrameRect);
  617.                     spritePoint = oldPoint;
  618.                     spritePoint.h += curSpriteP->horizMoveDelta;
  619.                     spritePoint.v += curSpriteP->vertMoveDelta;
  620.  
  621.                         // call it
  622.                     (*curSpriteP->spriteMoveProc)(curSpriteP, &spritePoint);
  623.  
  624.                     if ((spritePoint.h != oldPoint.h) || (spritePoint.v != oldPoint.v))
  625.                     {
  626.                         curSpriteP->destFrameRect.right  = (curSpriteP->destFrameRect.right -
  627.                                                             curSpriteP->destFrameRect.left) +
  628.                                                             spritePoint.h;
  629.                         curSpriteP->destFrameRect.bottom = (curSpriteP->destFrameRect.bottom -
  630.                                                             curSpriteP->destFrameRect.top) +
  631.                                                             spritePoint.v;
  632.                         curSpriteP->destFrameRect.left = spritePoint.h;
  633.                         curSpriteP->destFrameRect.top = spritePoint.v;
  634.  
  635.                         curSpriteP->needsToBeDrawn = true;
  636.                     }
  637.                 }
  638.                 else if ((curSpriteP->horizMoveDelta != 0) || (curSpriteP->vertMoveDelta != 0))
  639.                 {
  640.                         // offset destination rect (way faster than OffsetRect)
  641.                     curSpriteP->destFrameRect.top += curSpriteP->vertMoveDelta;
  642.                     curSpriteP->destFrameRect.left += curSpriteP->horizMoveDelta;
  643.                     curSpriteP->destFrameRect.bottom += curSpriteP->vertMoveDelta;
  644.                     curSpriteP->destFrameRect.right += curSpriteP->horizMoveDelta;
  645.  
  646.                     curSpriteP->needsToBeDrawn = true;
  647.                 }
  648.  
  649.                 if (curSpriteP->moveTimeInterval > 0)
  650.                 {
  651.                     curSpriteP->moveTimeTask.hasTaskFired = false;
  652.  
  653.                         // reset the time till next move
  654.                     PrimeTime((QElemPtr)&curSpriteP->moveTimeTask,
  655.                             curSpriteP->moveTimeInterval);
  656.                 }
  657.             }
  658.  
  659.             if (nextSpriteP != NULL)
  660.             {
  661.                 curSpriteP = nextSpriteP;
  662.             }
  663.             else
  664.             {
  665.                 curSpriteP = curSpriteP->nextSpriteP;
  666.             }
  667.         }
  668.  
  669.         if (nextSpriteLayerP != NULL)
  670.         {
  671.             curSpriteLayerP = nextSpriteLayerP;    
  672.         }
  673.         else
  674.         {
  675.             curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  676.         }
  677.     }
  678. }
  679.  
  680.  
  681. ///--------------------------------------------------------------------------------------
  682. //    SWAnimateSpriteWorld
  683. ///--------------------------------------------------------------------------------------
  684.  
  685. SW_FUNC void SWAnimateSpriteWorld(
  686.     SpriteWorldPtr spriteWorldP)
  687. {
  688.     register SpriteLayerPtr curSpriteLayerP;
  689.     register SpritePtr curSpriteP;
  690.     SpritePtr headActiveSpriteP = NULL;
  691.     SpritePtr curActiveSpriteP = NULL;
  692.  
  693.  
  694.     //-----------------erase the sprites--------------------
  695.  
  696.         // the current port should the one in which we are drawing    
  697.     SetPort(spriteWorldP->loadFrameP->framePort.monoGrafP);
  698.  
  699.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  700.  
  701.         // iterate through the layers in this world
  702.     while (curSpriteLayerP != NULL)
  703.     {
  704.         curSpriteP = curSpriteLayerP->headSpriteP;
  705.  
  706.             // iterate through the sprites in this layer
  707.         while (curSpriteP != NULL)
  708.         {
  709.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  710.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  711.             {
  712.                 if (headActiveSpriteP == NULL)
  713.                     headActiveSpriteP = curSpriteP;
  714.  
  715.                 if (curActiveSpriteP != NULL)
  716.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  717.  
  718.                 curActiveSpriteP = curSpriteP;
  719.  
  720.                     // union last rect and current rect
  721.                     // this way is much faster than UnionRect
  722.                 curSpriteP->deltaFrameRect.top =
  723.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  724.                 curSpriteP->deltaFrameRect.left =
  725.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  726.                 curSpriteP->deltaFrameRect.bottom =
  727.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  728.                 curSpriteP->deltaFrameRect.right =
  729.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  730.  
  731.                 {
  732.                     short temp;
  733.  
  734.                         // align the left edge to long word boundary
  735.                     curSpriteP->deltaFrameRect.left &=
  736.                             (spriteWorldP->loadFrameP->leftAlignFactor);
  737.  
  738.                         // align the right edge to long word boundary
  739.                     temp = curSpriteP->deltaFrameRect.right &
  740.                         spriteWorldP->loadFrameP->rightAlignFactor;
  741.                     if (temp != 0)
  742.                     {
  743.                         curSpriteP->deltaFrameRect.right +=
  744.                                 (spriteWorldP->loadFrameP->rightAlignFactor + 1) - temp;
  745.                     }
  746.  
  747.                         // align the left edge to long word boundary
  748.                     curSpriteP->oldFrameRect.left &=
  749.                         (spriteWorldP->loadFrameP->leftAlignFactor);
  750.  
  751.                         // align the right edge to long word boundary
  752.                     temp = curSpriteP->oldFrameRect.right &
  753.                         spriteWorldP->loadFrameP->rightAlignFactor;
  754.                     if (temp != 0)
  755.                     {
  756.                         curSpriteP->oldFrameRect.right +=
  757.                             (spriteWorldP->loadFrameP->rightAlignFactor + 1) - temp;
  758.                     }
  759.                 }
  760.  
  761.                     // copy the back drop piece
  762.                 (*spriteWorldP->eraseDrawProc)(
  763.                         spriteWorldP->backFrameP,
  764.                         spriteWorldP->loadFrameP,
  765.                         &curSpriteP->oldFrameRect);
  766.             }
  767.  
  768.             curSpriteP = curSpriteP->nextSpriteP;
  769.         }
  770.  
  771.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  772.     }
  773.  
  774.     if (curActiveSpriteP != NULL)
  775.             curActiveSpriteP->nextActiveSpriteP = NULL;
  776.  
  777.  
  778.     //-----------------draw the sprites--------------------
  779.  
  780.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  781.  
  782.         // iterate through the layers in this world
  783.     while (curSpriteLayerP != NULL)
  784.     {
  785.         curSpriteP = curSpriteLayerP->headSpriteP;
  786.  
  787.             // iterate through the sprites in this layer
  788.         while (curSpriteP != NULL)
  789.         {
  790.             if (curSpriteP->isVisible)
  791.             {
  792.                 if (curSpriteP->needsToBeDrawn)
  793.                 {
  794.                     if (curSpriteP->curFrameP->maskRgn != NULL)
  795.                     {
  796.                         Rect rgnRect = (**curSpriteP->curFrameP->maskRgn).rgnBBox;
  797.     
  798.                             // move the mask region to the new sprite location
  799.                         OffsetRgn(
  800.                             curSpriteP->curFrameP->maskRgn,
  801.                             (curSpriteP->destFrameRect.left - rgnRect.left) +
  802.                             curSpriteP->curFrameP->offsetPoint.h,
  803.                             (curSpriteP->destFrameRect.top - rgnRect.top) +
  804.                             curSpriteP->curFrameP->offsetPoint.v);
  805.                     }
  806.  
  807.                         // copy the sprite image onto the back drop piece
  808.                     (*curSpriteP->frameDrawProc)(
  809.                             curSpriteP->curFrameP,
  810.                             spriteWorldP->loadFrameP,
  811.                             &curSpriteP->curFrameP->frameRect,
  812.                             &curSpriteP->destFrameRect);
  813.                 }
  814.                 else
  815.                 {
  816.                     SWCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  817.                 }
  818.             }
  819.  
  820.             curSpriteP = curSpriteP->nextSpriteP;
  821.         }
  822.  
  823.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  824.     }
  825.  
  826.  
  827.     //-----------------update the screen--------------------
  828.  
  829.         // the current port should the one in which we are drawing    
  830.     SetPort(spriteWorldP->windowFrameP->framePort.monoGrafP);
  831.  
  832.     curSpriteP = headActiveSpriteP;
  833.  
  834.         // iterate through the sprites in this layer
  835.     while (curSpriteP != NULL)
  836.     {
  837.             // copy the backdrop+sprite piece from the loader to the screen
  838.         (*spriteWorldP->screenDrawProc)(
  839.                 spriteWorldP->loadFrameP,
  840.                 spriteWorldP->windowFrameP,
  841.                 &curSpriteP->deltaFrameRect);
  842.  
  843.             // set the delta and last rect to the current rect
  844.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  845.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  846.  
  847.             // this sprite no longer needs to be drawn
  848.         curSpriteP->needsToBeDrawn = false;
  849.         curSpriteP->needsToBeErased = false;
  850.  
  851.         curSpriteP = curSpriteP->nextActiveSpriteP;
  852.     }
  853. }
  854.  
  855.  
  856. ///--------------------------------------------------------------------------------------
  857. //    SWFastAnimateSpriteWorld
  858. ///--------------------------------------------------------------------------------------
  859.  
  860. SW_FUNC void SWFastAnimateSpriteWorld(
  861.     SpriteWorldPtr spriteWorldP)
  862. {
  863.     register SpriteLayerPtr curSpriteLayerP;
  864.     register SpritePtr curSpriteP;
  865.     SpritePtr headActiveSpriteP = NULL;
  866.     SpritePtr curActiveSpriteP = NULL;
  867. #if !SW_PPC
  868.     char mmuMode;
  869.  
  870.         // if we are already in 32 bit mode, then we don't have to incur the
  871.         // overhead of calling SwapMMUMode. if we are in 24 bit mode, we incur
  872.         // a neglible hit by checking before the swap.
  873.     if (gSWmmuMode != true32b)
  874.     {
  875.             // change to 32-bit addressing mode to access video memory
  876.             // the previous addressing mode is returned in mmuMode for restoring later
  877.         mmuMode = true32b;
  878.         SwapMMUMode(&mmuMode);
  879.     }
  880. #endif
  881.  
  882.     //-----------------erase the sprites--------------------
  883.  
  884.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  885.  
  886.         // iterate through the layers in this world
  887.     while (curSpriteLayerP != NULL)
  888.     {
  889.         curSpriteP = curSpriteLayerP->headSpriteP;
  890.  
  891.             // iterate through the sprites in this layer
  892.         while (curSpriteP != NULL)
  893.         {
  894.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  895.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  896.             {
  897.                 if (headActiveSpriteP == NULL)
  898.                     headActiveSpriteP = curSpriteP;
  899.  
  900.                 if (curActiveSpriteP != NULL)
  901.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  902.  
  903.                 curActiveSpriteP = curSpriteP;
  904.  
  905.                     // union last rect and current rect
  906.                     // this way is much faster than UnionRect
  907.                 curSpriteP->deltaFrameRect.top =
  908.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  909.                 curSpriteP->deltaFrameRect.left =
  910.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  911.                 curSpriteP->deltaFrameRect.bottom =
  912.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  913.                 curSpriteP->deltaFrameRect.right =
  914.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  915.  
  916.                 {
  917.                     short temp;
  918.  
  919.                         // align the left edge to long word boundary
  920.                     curSpriteP->deltaFrameRect.left &= kLeftAlignFactor;
  921.  
  922.                         // align the right edge to long word boundary
  923.                     temp = curSpriteP->deltaFrameRect.right & kRightAlignFactor;
  924.                     if (temp != 0)
  925.                     {
  926.                         curSpriteP->deltaFrameRect.right += (kRightAlignFactor+1) - temp;
  927.                     }
  928.  
  929.                         // align the left edge to long word boundary
  930.                     curSpriteP->oldFrameRect.left &= kLeftAlignFactor;
  931.  
  932.                         // align the right edge to long word boundary
  933.                     temp = curSpriteP->oldFrameRect.right & kRightAlignFactor;
  934.                     if (temp != 0)
  935.                     {
  936.                         curSpriteP->oldFrameRect.right += (kRightAlignFactor+1) - temp;
  937.                     }
  938.                 }
  939.  
  940.                     // copy the back drop piece
  941.                 (*spriteWorldP->eraseDrawProc)(
  942.                         spriteWorldP->backFrameP,
  943.                         spriteWorldP->loadFrameP,
  944.                         &curSpriteP->oldFrameRect);
  945.             }
  946.  
  947.             curSpriteP = curSpriteP->nextSpriteP;
  948.         }
  949.  
  950.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  951.     }
  952.  
  953.     if (curActiveSpriteP != NULL)
  954.             curActiveSpriteP->nextActiveSpriteP = NULL;
  955.  
  956.  
  957.     //-----------------draw the sprites--------------------
  958.  
  959.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  960.  
  961.         // iterate through the layers in this world
  962.     while (curSpriteLayerP != NULL)
  963.     {
  964.         curSpriteP = curSpriteLayerP->headSpriteP;
  965.  
  966.             // iterate through the sprites in this layer
  967.         while (curSpriteP != NULL)
  968.         {
  969.             if (curSpriteP->isVisible)
  970.             {
  971.                 if (curSpriteP->needsToBeDrawn)
  972.                 {
  973.                         // copy the sprite image onto the back drop piece
  974.                     (*curSpriteP->frameDrawProc)(
  975.                             curSpriteP->curFrameP,
  976.                             spriteWorldP->loadFrameP,
  977.                             &curSpriteP->curFrameP->frameRect,
  978.                             &curSpriteP->destFrameRect);
  979.                 }
  980.                 else
  981.                 {
  982.                     SWFastCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  983.                 }
  984.             }
  985.  
  986.             curSpriteP = curSpriteP->nextSpriteP;
  987.         }
  988.  
  989.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  990.     }
  991.  
  992.  
  993.     //-----------------update the screen--------------------
  994.  
  995.     curSpriteP = headActiveSpriteP;
  996.  
  997.         // iterate through the sprites in this layer
  998.     while (curSpriteP != NULL)
  999.     {
  1000.             // copy the backdrop+sprite piece from the loader to the screen
  1001.         (*spriteWorldP->screenDrawProc)(
  1002.                 spriteWorldP->loadFrameP,
  1003.                 spriteWorldP->windowFrameP,
  1004.                 &curSpriteP->deltaFrameRect);
  1005.  
  1006.             // set the delta and last rect to the current rect
  1007.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  1008.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  1009.  
  1010.             // this sprite no longer needs to be drawn
  1011.         curSpriteP->needsToBeDrawn = false;
  1012.         curSpriteP->needsToBeErased = false;
  1013.  
  1014.         curSpriteP = curSpriteP->nextActiveSpriteP;
  1015.     }
  1016.  
  1017. #if !SW_PPC
  1018.     if (gSWmmuMode != true32b)
  1019.     {
  1020.         SwapMMUMode(&mmuMode);
  1021.     }
  1022. #endif
  1023. }
  1024.  
  1025.  
  1026. ///--------------------------------------------------------------------------------------
  1027. //    SWBlastAnimateSpriteWorld
  1028. ///--------------------------------------------------------------------------------------
  1029.  
  1030. SW_FUNC void SWBlastAnimateSpriteWorld(
  1031.     SpriteWorldPtr spriteWorldP)
  1032. {
  1033.     register SpriteLayerPtr curSpriteLayerP;
  1034.     register SpritePtr curSpriteP;
  1035.     SpritePtr headActiveSpriteP = NULL;
  1036.     SpritePtr curActiveSpriteP = NULL;
  1037. #if !SW_PPC
  1038.     char mmuMode;
  1039.  
  1040.         // if we are already in 32 bit mode, then we don't have to incur the
  1041.         // overhead of calling SwapMMUMode. if we are in 24 bit mode, we incur
  1042.         // a neglible hit by checking before the swap.
  1043.     if (gSWmmuMode != true32b)
  1044.     {
  1045.             // change to 32-bit addressing mode to access video memory
  1046.             // the previous addressing mode is returned in mmuMode for restoring later
  1047.         mmuMode = true32b;
  1048.         SwapMMUMode(&mmuMode);
  1049.     }
  1050. #endif
  1051.  
  1052.     //-----------------erase the sprites--------------------
  1053.  
  1054.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;    
  1055.  
  1056.         // iterate through the layers in this world
  1057.     while (curSpriteLayerP != NULL)
  1058.     {
  1059.         curSpriteP = curSpriteLayerP->headSpriteP;
  1060.  
  1061.             // iterate through the sprites in this layer
  1062.         while (curSpriteP != NULL)
  1063.         {
  1064.             if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
  1065.                 (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
  1066.             {
  1067.                 if (headActiveSpriteP == NULL)
  1068.                     headActiveSpriteP = curSpriteP;
  1069.  
  1070.                 if (curActiveSpriteP != NULL)
  1071.                         curActiveSpriteP->nextActiveSpriteP = curSpriteP;
  1072.  
  1073.                 curActiveSpriteP = curSpriteP;
  1074.  
  1075.                     // union last rect and current rect
  1076.                     // this way is much faster than UnionRect
  1077.                 curSpriteP->deltaFrameRect.top =
  1078.                     SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
  1079.                 curSpriteP->deltaFrameRect.left =
  1080.                     SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
  1081.                 curSpriteP->deltaFrameRect.bottom =
  1082.                     SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
  1083.                 curSpriteP->deltaFrameRect.right =
  1084.                     SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
  1085.  
  1086.                 {
  1087.                     short temp;
  1088.  
  1089.                         // align the left edge to long word boundary
  1090.                     curSpriteP->deltaFrameRect.left &= kLeftAlignFactor;
  1091.  
  1092.                         // align the right edge to long word boundary
  1093.                     temp = curSpriteP->deltaFrameRect.right & kRightAlignFactor;
  1094.                     if (temp != 0)
  1095.                     {
  1096.                         curSpriteP->deltaFrameRect.right += (kRightAlignFactor+1) - temp;
  1097.                     }
  1098.  
  1099.                         // align the left edge to long word boundary
  1100.                     curSpriteP->oldFrameRect.left &= kLeftAlignFactor;
  1101.  
  1102.                         // align the right edge to long word boundary
  1103.                     temp = curSpriteP->oldFrameRect.right & kRightAlignFactor;
  1104.                     if (temp != 0)
  1105.                     {
  1106.                         curSpriteP->oldFrameRect.right += (kRightAlignFactor+1) - temp;
  1107.                     }
  1108.                 }
  1109.  
  1110.                     // copy the back drop piece
  1111.                 BlitPixieWorldDrawProc(
  1112.                         spriteWorldP->backFrameP,
  1113.                         spriteWorldP->loadFrameP,
  1114.                         &curSpriteP->oldFrameRect);
  1115.             }
  1116.  
  1117.             curSpriteP = curSpriteP->nextSpriteP;
  1118.         }
  1119.  
  1120.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;    
  1121.     }
  1122.  
  1123.     if (curActiveSpriteP != NULL)
  1124.             curActiveSpriteP->nextActiveSpriteP = NULL;
  1125.  
  1126.  
  1127.     //-----------------draw the sprites--------------------
  1128.  
  1129.     curSpriteLayerP = spriteWorldP->headSpriteLayerP;
  1130.  
  1131.         // iterate through the layers in this world
  1132.     while (curSpriteLayerP != NULL)
  1133.     {
  1134.         curSpriteP = curSpriteLayerP->headSpriteP;
  1135.  
  1136.             // iterate through the sprites in this layer
  1137.         while (curSpriteP != NULL)
  1138.         {
  1139.             if (curSpriteP->isVisible)
  1140.             {
  1141.                 if (curSpriteP->needsToBeDrawn)
  1142.                 {
  1143.                             // jump into the compiled mask code
  1144.                     (*curSpriteP->frameDrawProc)(
  1145.                             curSpriteP->curFrameP,
  1146.                             spriteWorldP->loadFrameP,
  1147.                             &curSpriteP->curFrameP->frameRect,
  1148.                             &curSpriteP->destFrameRect);
  1149.                 }
  1150.                 else
  1151.                 {
  1152.                     SWFastCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
  1153.                 }
  1154.             }
  1155.  
  1156.             curSpriteP = curSpriteP->nextSpriteP;
  1157.         }
  1158.  
  1159.         curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
  1160.     }
  1161.  
  1162.  
  1163.     //-----------------update the screen--------------------
  1164.  
  1165.     curSpriteP = headActiveSpriteP;
  1166.  
  1167.         // iterate through the sprites in this layer
  1168.     while (curSpriteP != NULL)
  1169.     {
  1170.             // copy the backdrop+sprite piece from the loader to the screen
  1171.         BlitPixieWorldDrawProc(
  1172.                 spriteWorldP->loadFrameP,
  1173.                 spriteWorldP->windowFrameP,
  1174.                 &curSpriteP->deltaFrameRect);
  1175.  
  1176.             // set the delta and last rect to the current rect
  1177.         curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
  1178.         curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
  1179.  
  1180.             // this sprite no longer needs to be drawn
  1181.         curSpriteP->needsToBeDrawn = false;
  1182.         curSpriteP->needsToBeErased = false;
  1183.  
  1184.         curSpriteP = curSpriteP->nextActiveSpriteP;
  1185.     }
  1186.  
  1187. #if !SW_PPC
  1188.     if (gSWmmuMode != true32b)
  1189.     {
  1190.         SwapMMUMode(&mmuMode);
  1191.     }
  1192. #endif
  1193. }
  1194.  
  1195.  
  1196. ///--------------------------------------------------------------------------------------
  1197. //    SWCheckIdleSpriteOverlap
  1198. ///--------------------------------------------------------------------------------------
  1199.  
  1200. static void SWCheckIdleSpriteOverlap(
  1201.     SpriteWorldPtr spriteWorldP,
  1202.     register SpritePtr idleSpriteP,
  1203.     SpritePtr headActiveSpriteP)
  1204. {
  1205.     register SpritePtr activeSpriteP;
  1206.     RgnHandle maskRgn = idleSpriteP->curFrameP->maskRgn;
  1207.  
  1208.     activeSpriteP = headActiveSpriteP;
  1209.  
  1210.         // iterate through the active sprites
  1211.     while (activeSpriteP != NULL)
  1212.     {
  1213.             // do the sprites overlap?
  1214.         if ((idleSpriteP->destFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
  1215.              (idleSpriteP->destFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
  1216.              (idleSpriteP->destFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
  1217.              (idleSpriteP->destFrameRect.right > activeSpriteP->deltaFrameRect.left))
  1218.         {
  1219.             Rect srcSectRect, dstSectRect;
  1220.  
  1221.             if (maskRgn != NULL)
  1222.             {
  1223.                     // move the mask region to the new sprite location
  1224.                 OffsetRgn(
  1225.                     maskRgn,
  1226.                     (idleSpriteP->destFrameRect.left - (**maskRgn).rgnBBox.left) +
  1227.                     idleSpriteP->curFrameP->offsetPoint.h,
  1228.                     (idleSpriteP->destFrameRect.top - (**maskRgn).rgnBBox.top) +
  1229.                     idleSpriteP->curFrameP->offsetPoint.v);
  1230.  
  1231.                 maskRgn = NULL;
  1232.             }
  1233.  
  1234.                 // calculate the intersection between the idle sprite's destination
  1235.                 // rect, and the active sprite's old rect
  1236.             dstSectRect.left =
  1237.                     SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
  1238.             dstSectRect.top =
  1239.                     SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
  1240.             dstSectRect.right =
  1241.                     SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
  1242.             dstSectRect.bottom =
  1243.                     SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
  1244.  
  1245.             srcSectRect = dstSectRect;
  1246.  
  1247.             srcSectRect.left -= idleSpriteP->destFrameRect.left;
  1248.             srcSectRect.right -= idleSpriteP->destFrameRect.left;
  1249.             srcSectRect.top -= idleSpriteP->destFrameRect.top;
  1250.             srcSectRect.bottom -= idleSpriteP->destFrameRect.top;
  1251.  
  1252.                 // copy a piece of the sprite image onto the back drop piece
  1253.             (*idleSpriteP->frameDrawProc)(
  1254.                     idleSpriteP->curFrameP,
  1255.                     spriteWorldP->loadFrameP,
  1256.                     &srcSectRect,
  1257.                     &dstSectRect);
  1258.         }
  1259.  
  1260.         activeSpriteP = activeSpriteP->nextActiveSpriteP;
  1261.     }
  1262. }
  1263.  
  1264.  
  1265. ///--------------------------------------------------------------------------------------
  1266. //    SWFastCheckIdleSpriteOverlap
  1267. ///--------------------------------------------------------------------------------------
  1268.  
  1269. static void SWFastCheckIdleSpriteOverlap(
  1270.     SpriteWorldPtr spriteWorldP,
  1271.     register SpritePtr idleSpriteP,
  1272.     SpritePtr headActiveSpriteP)
  1273. {
  1274.     register SpritePtr activeSpriteP = headActiveSpriteP;
  1275.  
  1276.         // iterate through the active sprites
  1277.     while (activeSpriteP != NULL)
  1278.     {
  1279.             // do the sprites overlap?
  1280.         if ((idleSpriteP->destFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
  1281.              (idleSpriteP->destFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
  1282.              (idleSpriteP->destFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
  1283.              (idleSpriteP->destFrameRect.right > activeSpriteP->deltaFrameRect.left))
  1284.         {
  1285.             Rect srcSectRect, dstSectRect;
  1286.  
  1287.                 // calculate the intersection between the idle sprite's destination
  1288.                 // rect, and the active sprite's old rect
  1289.             dstSectRect.left =
  1290.                     SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
  1291.             dstSectRect.top =
  1292.                     SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
  1293.             dstSectRect.right =
  1294.                     SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
  1295.             dstSectRect.bottom =
  1296.                     SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
  1297.  
  1298.             srcSectRect = dstSectRect;
  1299.  
  1300.             srcSectRect.left -= idleSpriteP->destFrameRect.left;
  1301.             srcSectRect.right -= idleSpriteP->destFrameRect.left;
  1302.             srcSectRect.top -= idleSpriteP->destFrameRect.top;
  1303.             srcSectRect.bottom -= idleSpriteP->destFrameRect.top;
  1304.  
  1305.                 // copy a piece of the sprite image onto the back drop piece
  1306.             (*idleSpriteP->frameDrawProc)(
  1307.                     idleSpriteP->curFrameP,
  1308.                     spriteWorldP->loadFrameP,
  1309.                     &srcSectRect,
  1310.                     &dstSectRect);
  1311.         }
  1312.  
  1313.         activeSpriteP = activeSpriteP->nextActiveSpriteP;
  1314.     }
  1315. }
  1316.  
  1317.  
  1318.